<?php
class CodeSpace_Oauth_Server
{
    const REQUEST_TOKEN_REQUEST = 'REQUEST_REQUEST_TOKEN';
    const REQUEST_TOKEN_ACCESS = 'REQUEST_ACCESS_TOKEN';
    const REQUEST_SERVICE = 'REQUEST_SERVICE';
    const REQUEST_TRANSMISSION = 'REQUEST_TRANSMISSION';
    const REQUEST_AUTHORIZATION = 'REQUEST_AUTHORIZATION';

    protected $_accessTokenRequestUrl = null;
    protected $_requestTokenRequestUrl = null;
    protected $_authorizatioRequestUrl = null;
    protected $_serviceRequestUrl = null;
    protected $_transmissionRequestUrl = null;
    
    protected $_requestType = null;

    protected $_config = null;
    
    protected $_request = null;

    public function __construct ($options = null)
    {
        $this->_config = new CodeSpace_Oauth_Server_Config();
        
        if (is_null($options))
        {
            $options = array_merge($_POST, $_GET);  
        }

        $this->setOptions($options);
    }
    
    public function setOptions(array $options)
    {
        if ($options instanceof Zend_Config)
        {
            $options = $options->toArray();
        }
        
        $this->_config->setOptions($options);
    }
    
    public function setAccessTokenRequestUrl($url)
    {
        $this->_accessTokenRequestUrl = $url;
    }
    
    public function setRequestTokenRequestUrl($url)
    {
        $this->_requestTokenRequestUrl = $url;
    }
    
    public function setAuthorizationRequestUrl($url)
    {
        $this->_authorizatioRequestUrl = $url;
    }
    
    public function setSericeRequestUrl($url)
    {
        $this->_serviceRequestUrl = $url;
    }
    
    public function setTransmissionRequestUrl($url)
    {
        $this->_transmissionRequestUrl = $url;
    }
    
    public function setRequest()
    {
        $requestUrl = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REDIRECT_URL'];
        
        switch ($requestUrl)
        {
            case $this->_requestTokenRequestUrl:
                $request = new CodeSpace_Oauth_Server_Request_Token_Request();
                $this->_requestType = self::REQUEST_TOKEN_REQUEST;
                break;
            case $this->_accessTokenRequestUrl:
                $request = new CodeSpace_Oauth_Server_Request_Token_Access();
                $this->_requestType = self::REQUEST_TOKEN_ACCESS;
                break;    
            case $this->_authorizatioRequestUrl:
                $request = new CodeSpace_Oauth_Server_Request_Authorization();
                $this->_requestType = self::REQUEST_AUTHORIZATION;
                break;
            case $this->_serviceRequestUrl:
                $this->_requestType = self::REQUEST_SERVICE;
                break;
            case $this->_transmissionRequestUrl:
                $this->_requestType = self::REQUEST_TRANSMISSION;
                break;
            case 'authorizationcallback':
                $this->_processAuthorizationCallback();
                break;
            default:
                $request = new CodeSpace_Oauth_Server_Request_Transmission();
                //$this->_oauthServer = new CodeSpace_Oauth_Server_Request_Transmission($options);
                break;
        }
        
        $this->_request = $request;
    }
    
    public function getRequestType()
    {
        return $this->_requestType;
    }
    
    public function getRequest()
    {
        return $this->_request;
    }
    
    public function getConfig()
    {
        return $this->_config;
    }

    public function checkNonce ()
    {
        return true;
    }
    
    public function handle()
    {
        if($this->_requestType != self::REQUEST_AUTHORIZATION)
        {
            $this->_checkOauthParameters();
            $this->_checkConsumer();
            //$this->_checkSignature();
            $this->_checkOauthRequest();
        }

       $this->_request->process($this);
    }
    
    protected function _checkConsumer()
    {
        $consumer = $this->getConsumer();
        
        if(!$consumer->authenticate())
        {
            throw new Exception('Wrong Consumer Key');
        }
        
        return true;
    }

    protected function _checkSignature ()
    {
        $controlSignature = $this->_request->buildControlSignature($this->_config);
         
        if ($controlSignature != $this->_config->getSignature())
        {
            throw new Exception('Invalid Signature ' . $controlSignature . ' with ' . $this->_config->getSignature() . '   =>  ' . $this->_requestType);
        }
        
        return true;
    }


    protected function _checkOauthParameters ()
    {
        // Checks the correct parameters are sent according to the incoming request
        return true;
    }
    
    protected function _checkOauthRequest ()
    {
        // Check for NONCE and TIMESTAMP
    }

	/**
     * Simple Proxy to the current CodeSpace_Oauth_Config method. It's that instance
     * which holds all configuration methods and values this object also presents
     * as it's API.
     *
     * @param  string $method
     * @param  array $args
     * @return mixed
     * @throws Zend_Oauth_Exception if method does not exist in config object
     */
    public function __call ($method, array $args)
    {
        if (! method_exists($this->_config, $method))
        {
            throw new Exception('Method does not exist: ' . $method);
        }
        return call_user_func_array(array ($this->_config, $method), $args);
    }
    
    public function debug ($override = false, $params = null)
    {
        if ($override)
        {
            $fp = fopen(APPLICATION_PATH . '/../public/data.txt', 'w');
        }
        else
        {
            $fp = fopen(APPLICATION_PATH . '/../public/data.txt', 'a');
        }
        fwrite($fp, $this->_getDebugData($params));
        fclose($fp);
    }

    private function _getDebugData ($params = null)
    {
        $print = '';
        
        if($params != null)
        {
            $print .= "\r\n" . "===========================CUSTOM PARAMS==========================" . "\r\n";
            foreach ($params as $k => $v)
            {
                $print .= $k . ' ====> ' . $v . "\r\n";
            }
            $print .= "\r\n";
        }
        
        $print .= "\r\n" .
         "===========================HEADER==========================" . "\r\n";
        $front = Zend_Controller_Front::getInstance();
        $request = $front->getRequest();
        $headers = $request->getHeader('Authorization');
        $print .= 'Authorization ====> ' . $headers . "\r\n";
        $print .= "\r\n" .
         "===========================SERVER==========================" . "\r\n";
        foreach ($_SERVER as $k => $v)
        {
            $print .= $k . ' ====> ' . $v . "\r\n";
        }
        $print .= "\r\n" .
         '===========================GET==========================' . "\r\n";
        foreach ($_GET as $k => $v)
        {
            $print .= $k . ' ====> ' . $v . "\r\n";
        }
        $print .= "\r\n" .
         '===========================POST==========================' . "\r\n";
        foreach ($_POST as $k => $v)
        {
            $print .= $k . ' ====> ' . $v . "\r\n";
        }
        $print .= "\r\n" .
         '===========================REQUEST==========================' . "\r\n";
        foreach ($_REQUEST as $k => $v)
        {
            $print .= $k . ' ====> ' . $v . "\r\n";
        }
        return $print;
    }

    
}
?>